package com.atguigu.tingshu.payment.service.impl;

import com.atguigu.tingshu.account.AccountFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.account.RechargeInfo;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.payment.PaymentInfo;
import com.atguigu.tingshu.order.client.OrderFeignClient;
import com.atguigu.tingshu.payment.mapper.PaymentInfoMapper;
import com.atguigu.tingshu.payment.service.PaymentInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.ExecutionException;

@Service
@SuppressWarnings({"all"})
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {


    @Autowired
    private PaymentInfoMapper paymentInfoMapper;

    @Autowired
    private OrderFeignClient orderFeignClient;

    @Autowired
    private AccountFeignClient accountFeignClient;

    /**
     * 保存本地交易记录
     *
     * @param paymentType:支付类型 1301-订单 1302-充值
     * @param orderNo:         订单编号或者充值编号
     * @return
     */
    @Override
    public PaymentInfo savePaymentInfo(String paymentType, String orderNo) {
        //1.根据支付类型+订单编号查询本地交易记录信息
        LambdaQueryWrapper<PaymentInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PaymentInfo::getPaymentType, paymentType);
        queryWrapper.eq(PaymentInfo::getOrderNo, orderNo);
        PaymentInfo paymentInfo = paymentInfoMapper.selectOne(queryWrapper);
        //2.如果已存在交易记录，直接返回
        if (paymentInfo != null) {
            return paymentInfo;
        }
        //3.如果不存在交易记录，新增交易记录
        paymentInfo = new PaymentInfo();
        //3.1 支付类型：1301-订单 1302-充值
        paymentInfo.setPaymentType(paymentType);
        paymentInfo.setPayWay(SystemConstant.ORDER_PAY_WAY_WEIXIN);
        paymentInfo.setPaymentStatus(SystemConstant.PAYMENT_STATUS_UNPAID);
        paymentInfo.setOrderNo(orderNo);
        //3.2 判断支付类型：订单
        if (SystemConstant.PAYMENT_TYPE_ORDER.equals(paymentType)) {
            //3.2.1 远程调用订单服务获取订单信息
            OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderNo).getData();
            //3.2.2 判断订单支付状态：如果是已支付或已关闭 结束抛出异常终止业务
            if (SystemConstant.ORDER_STATUS_PAID.equals(orderInfo.getOrderStatus()) || SystemConstant.ORDER_STATUS_CANCEL.equals(orderInfo.getOrderStatus())) {
                throw new RuntimeException("订单已支付或已关闭");
            }
            //3.2.3 订单金额
            paymentInfo.setAmount(orderInfo.getOrderAmount());
            //3.2.4 订单内容
            paymentInfo.setContent(orderInfo.getOrderTitle());
            //3.2.5 用户ID
            paymentInfo.setUserId(orderInfo.getUserId());
        }
        if (SystemConstant.PAYMENT_TYPE_RECHARGE.equals(paymentType)) {
            //3.3 判断支付类型：充值
            //3.3.1 远程调用账户服务获取充值记录
            RechargeInfo rechargeInfo = accountFeignClient.getRechargeInfo(orderNo).getData();
            //3.3.2 判断充值记录交易状态 如果是已支付或已关闭 结束抛出异常终止业务
            if (SystemConstant.PAYMENT_STATUS_PAID.equals(rechargeInfo.getRechargeStatus())) {
                throw new RuntimeException("充值已支付");
            }
            //3.3.3 为本地交易记录属性赋值
            paymentInfo.setAmount(rechargeInfo.getRechargeAmount());
            paymentInfo.setContent("充值:" + rechargeInfo.getRechargeAmount());
            paymentInfo.setUserId(rechargeInfo.getUserId());
        }
        //3.4 保存交易记录
        paymentInfoMapper.insert(paymentInfo);
        return paymentInfo;
    }

    /**
     * 用户付款成功后，更新本地交易记录及关联的订单或充值相关业务处理
     *
     * @param transaction
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void handlerPaymentInfo(Transaction transaction) {
        //1.核心业务1：更新本地交易-支付状态、回调内容、回调时间、微信端交易编号
        //1.1 获取交易对应商户订单编号
        String orderNo = transaction.getOutTradeNo();
        //1.2 根据订单编号查询本地交易记录
        PaymentInfo paymentInfo = paymentInfoMapper.selectOne(new LambdaQueryWrapper<PaymentInfo>().eq(PaymentInfo::getOrderNo, orderNo));
        if (paymentInfo != null && SystemConstant.PAYMENT_STATUS_UNPAID.equals(paymentInfo.getPaymentStatus())) {
            //1.3 获取到微信交易订单编号
            String transactionId = transaction.getTransactionId();
            paymentInfo.setPaymentStatus(SystemConstant.PAYMENT_STATUS_PAID);
            paymentInfo.setOutTradeNo(transactionId);
            paymentInfo.setCallbackTime(new Date());
            paymentInfo.setCallbackContent(transaction.toString());
            paymentInfoMapper.updateById(paymentInfo);

            //支付类型：1301-订单 1302-充值
            String paymentType = paymentInfo.getPaymentType();
            //2.核心业务2-如果交易类型是订单，远程调用订单服务更新订单并且完成虚拟物品发货
            if (SystemConstant.PAYMENT_TYPE_ORDER.equals(paymentType)) {
                //2.1 远程调用订单服务修改订单状态：已支付
                Result result = orderFeignClient.orderPaySuccess(orderNo);
                if (!result.getCode().equals(200)) {
                    throw new RuntimeException("远程调用-更新订单状态异常");
                }
            }
            //3.TODO 核心业务3-如果交易类型是充值，远程调用账户服务完成充值业务
            if (SystemConstant.PAYMENT_TYPE_RECHARGE.equals(paymentType)) {
                Result result = accountFeignClient.rechargePaySuccess(orderNo);
                if (!result.getCode().equals(200)) {
                    throw new RuntimeException("远程调用-充值异常");
                }
            }
        }
    }
}
